function fig = fm_plotsel(varargin)
% FM_PLOTSEL create GUI to select plotting variables
%
% HDL = FM_PLOTSEL()
%
%Author:    Federico Milano
%Date:      21-Dec-2005
%Version:   1.0.0
%
%E-mail:    Federico.Milano@uclm.es
%Web-site:  http://www.uclm.es/area/gsee/Web/Federico
%
% Copyright (C) 2002-2013 Federico Milano

global Fig Theme Varname Settings File Path

% check for data file
if isempty(File.data)
  fm_disp('Set a data file before selecting plot variables.',2)
  return
end
% check for initial power flow solution
if ~Settings.init
  fm_disp('Solve base case power flow...')
  Settings.show = 0;
  fm_set lf
  Settings.show = 1;
  if ~Settings.init, return, end
end

if nargin
  switch varargin{1}

   case 'area'

    values = get(gcbo,'Value')-1;
    if ~values(1)
      values = 0;
      set(gcbo,'Value',1)
    end
    Varname.areas = values;
    setidx

   case 'region'

    values = get(gcbo,'Value')-1;
    if ~values(1)
      values = 0;
      set(gcbo,'Value',1)
    end
    Varname.regions = values;
    setidx

   case 'selvars'

    values = get(gcbo,'Value');
    hdl = findobj(gcf,'Tag','listbox2');
    Varname.idx = values;
    setidx

   case 'selection'

    if isempty(Varname.idx)
      set(gcbo,'String','<Empty>','Value',1)
    elseif Varname.idx(end) > Varname.nvars
      set(gcbo,'String','<Empty>','Value',1)
      Varname.idx = [];
    else
      set(gcbo,'String',Varname.uvars(Varname.idx),'Value',1)
    end

   case 'remove'

    hdl = findobj(gcf,'Tag','listbox2');
    values = get(hdl,'Value');
    Varname.idx(values) = [];
    if isempty(Varname.idx)
      set(hdl,'String','<Empty>')
    else
      nidx = length(Varname.idx);
      toplist = max(1,nidx-8);
      set(hdl,'String',Varname.uvars(Varname.idx), ...
              'Value',min(max(values),nidx), ...
              'ListboxTop',toplist)
    end

   case 'create_custom'

    setarea(0,1,'on','off')

   case 'creates_fixed'

    setarea(1,0,'off','on')

   case 'custom'

    setarea(0,1,'on','off')
    setidx

   case 'fixed'

    setarea(1,0,'off','on')
    setidx

   case 'setx'

    Varname.x = get(gcbo,'Value');
    setidx

   case 'sety'

    Varname.y = get(gcbo,'Value');
    setidx

   case 'setP'

    Varname.P = get(gcbo,'Value');
    setidx

   case 'setQ'

    Varname.Q = get(gcbo,'Value');
    setidx

   case 'setPij'

    Varname.Pij = get(gcbo,'Value');
    setidx

   case 'setQij'

    Varname.Qij = get(gcbo,'Value');
    setidx

   case 'setIij'

    Varname.Iij = get(gcbo,'Value');
    setidx

   case 'setSij'

    Varname.Sij = get(gcbo,'Value');
    setidx

   case 'appendidx'

    if isempty(File.data),
      fm_disp('No data file loaded.',2),
      return,
    end
    filedata = strrep(File.data,'@ ','');
    if Settings.init == 0,
      fm_disp('Run power flow before saving plot variable indexes.',2),
      return,
    end
    if isempty(strfind(filedata,'(mdl)'))
      fid = fopen([Path.data,filedata,'.m'],'r+');
      count = fseek(fid,0,1);
      count = fprintf(fid, '\n\nVarname.idx = [...\n');
      nidx = length(Varname.idx);
      count = fprintf(fid,'%5d; %5d; %5d; %5d; %5d; %5d; %5d;\n',Varname.idx);
      if rem(nidx,7) ~= 0,
        count = fprintf(fid,'\n');
      end
      count = fprintf(fid,'   ];\n');
      count = fprintf(fid, '\nVarname.areas = [...\n');
      nidx = length(Varname.areas);
      count = fprintf(fid,'%5d; %5d; %5d; %5d; %5d; %5d; %5d;\n',Varname.areas);
      if rem(nidx,7) ~= 0,
        count = fprintf(fid,'\n');
      end
      count = fprintf(fid,'   ];\n');
      count = fprintf(fid, '\nVarname.regions = [...\n');
      nidx = length(Varname.regions);
      count = fprintf(fid,'%5d; %5d; %5d; %5d; %5d; %5d; %5d;\n',Varname.regions);
      if rem(nidx,7) ~= 0,
        count = fprintf(fid,'\n');
      end
      count = fprintf(fid,'   ];\n');
      fclose(fid);
      fm_disp(['Plot variable indexes appended to file "',Path.data,File.data,'"'])
    else
      % load Simulink Library and add Varname block
      load_system('fm_lib');
      cd(Path.data);
      filedata = filedata(1:end-5);
      open_sys = find_system('type','block_diagram');
      if ~sum(strcmp(open_sys,filedata))
        open_system(filedata);
      end
      cur_sys = get_param(filedata,'Handle');
      blocks = find_system(cur_sys,'MaskType','Varname');
      if ~isempty(blocks)
        if iscell(blocks)
          varblock = blocks{1};
          % remove duplicate 'Varname' blocks
          for i = 2:length(blocks)
            delete_block(blocks{i});
          end
        else
          varblock = blocks;
        end
        vec = Varname.idx;
        if size(vec,1) > 1, vec = vec'; end
        set_param( ...
            varblock, 'pxq', ...
            ['[',regexprep(num2str(vec),'\s*','  '),']'])
      else
        vec = Varname.idx;
        if size(vec,1) > 1, vec = vec'; end
        add_block( ...
            'fm_lib/Connections/Varname',[filedata,'/Varname'], 'pxq', ...
            ['[',regexprep(num2str(vec),'\s*','  '),']'], ...
            'Position',[20,20,105,57])
      end
      cd(Path.local);
    end
  end

  return

end

if Fig.plotsel > 0, figure(Fig.plotsel), return, end

h0 = figure(...
    'Units','normalized',...
    'Color',Theme.color01,...
    'Colormap',[], ...
    'MenuBar','none',...
    'Name','Select Plot Variables',...
    'NumberTitle','off',...
    'Position',sizefig(0.75,0.69), ...
    'FileName','fm_plotsel', ...
    'HandleVisibility','callback',...
    'Tag','figure1',...
    'CreateFcn','Fig.plotsel = gcf;', ...
    'DeleteFcn','Fig.plotsel = 0;', ...
    'UserData',[],...
    'Visible','on');

% Menu File
h1 = uimenu('Parent',h0, ...
  'Label','File', ...
  'Tag','MenuFile');
h2 = uimenu('Parent',h1, ...
  'Callback','close(gcf)', ...
  'Label','Exit', ...
  'Tag','PlotSelExit', ...
  'Accelerator','x');

h1 = uipanel(...
    'Parent',h0, ...
    'Title','Variables', ...
    'BackgroundColor',Theme.color02, ...
    'Units','normalized',...
    'Tag','uipanel1',...
    'Clipping','on',...
    'Position',[0.0611 0.2717 0.2506 0.6359]);

idx = Varname.idx;
if isempty(idx), idx = 1; end

h1 = uicontrol(...
    'Parent',h1, ...
    'BackgroundColor',Theme.color03, ...
    'Callback','fm_plotsel selvars', ...
    'FontName',Theme.font01, ...
    'Max',20, ...
    'ForegroundColor',Theme.color06, ...
    'Units','normalized',...
    'Position',[0.1015 0.0597 0.8071 0.8985],...
    'String',Varname.uvars,...
    'Style','listbox',...
    'Value',idx,...
    'Tag','listbox1');

h1 = uipanel(...
    'Parent',h0, ...
    'Title','Selection', ...
    'BackgroundColor',Theme.color02, ...
    'Units','normalized',...
    'Tag','uipanel2',...
    'Clipping','on',...
    'Position',[0.6833 0.2717 0.2506 0.6359]);

h5 = uicontrol(...
    'Parent',h1, ...
    'Units','normalized',...
    'BackgroundColor',Theme.color03, ...
    'CreateFcn','fm_plotsel selection', ...
    'Max',20, ...
    'FontName',Theme.font01, ...
    'ForegroundColor',Theme.color06, ...
    'Position',[0.1015 0.0597 0.8071 0.9015],...
    'String',{  '<Empty>' },...
    'Style','listbox',...
    'Value',1,...
    'Tag','listbox2');

set(h5,'Value',max(1,length(Varname.idx)-8))

h4 = uipanel(...
    'Parent',h0,...
    'Title','Region',...
    'BackgroundColor',Theme.color02, ...
    'Tag','uipanel2',...
    'Clipping','on',...
    'Position',[0.3728 0.6341 0.2506 0.2736]);

h5 = uicontrol(...
    'Parent',h4,...
    'BackgroundColor',Theme.color03, ...
    'ForegroundColor',Theme.color06, ...
    'CreateFcn','set(gcbo,''String'',[{''<all>''};Regions.names])', ...
    'Callback','fm_plotsel region', ...
    'Max',20, ...
    'FontName',Theme.font01, ...
    'Units','normalized',...
    'Position',[0.1015 0.1333 0.8020 0.7630],...
    'String',{ '<empty>' },...
    'Style','listbox',...
    'Value',1,...
    'Tag','listbox3');

if ~Varname.regions(1)
  Varname.regions = 0;
  set(h5,'Value',1)
else
  set(h5,'Value',Varname.regions+1);
end

h6 = uipanel(...
    'Parent',h0,...
    'Title','Area',...
    'BackgroundColor',Theme.color02, ...
    'Tag','uipanel3',...
    'Clipping','on',...
    'Position',[0.3716 0.2736 0.2506 0.2736]);

h7 = uicontrol(...
    'Parent',h6,...
    'BackgroundColor',Theme.color03, ...
    'ForegroundColor',Theme.color06, ...
    'CreateFcn','set(gcbo,''String'',[{''<all>''};Areas.names])', ...
    'Callback','fm_plotsel area', ...
    'Max',20, ...
    'FontName',Theme.font01, ...
    'Units','normalized',...
    'Position',[0.1066 0.1185 0.8020 0.7852],...
    'String',{  '<Empty>' },...
    'Style','listbox',...
    'Value',1,...
    'Tag','listbox4');

if ~Varname.areas(1)
  Varname.areas = 0;
  set(h7,'Value',1)
else
  set(h7,'Value',Varname.areas+1);
end

h8 = uicontrol(...
    'Parent',h0, ...
    'Units','normalized',...
    'BackgroundColor',Theme.color03, ...
    'FontWeight','bold', ...
    'ForegroundColor',Theme.color09, ...
    'Callback','close(gcf);', ...
    'Position',[0.8092 0.1087 0.1259 0.0580],...
    'String','Close',...
    'Tag','Pushbutton1');

h8 = uicontrol(...
    'Parent',h0, ...
    'Callback','fm_plotsel appendidx', ...
    'Units','normalized',...
    'BackgroundColor',Theme.color02, ...
    'Position',[0.6222 0.1087 0.1259 0.0598],...
    'String','Save',...
    'Tag','Pushbutton2');

h10 = uicontrol(...
    'CData',fm_mat('plotsel_pij'), ...
    'Parent',h0, ...
    'Units','normalized',...
    'Callback','fm_plotsel setPij', ...
    'HorizontalAlignment','center', ...
    'Position',[0.0611 0.0453 0.0623 0.0924],...
    'String','',...
    'Value',Varname.Pij,...
    'Style','togglebutton',...
    'Tag','radiobutton1');

h11 = uicontrol(...
    'CData',fm_mat('plotsel_qij'), ...
    'Parent',h0, ...
    'Units','normalized',...
    'Callback','fm_plotsel setQij', ...
    'HorizontalAlignment','center', ...
    'Position',[0.1297 0.0453 0.0623 0.0924],...
    'String','',...
    'Value',Varname.Qij,...
    'Style','togglebutton',...
    'Tag','radiobutton2');

h12 = uicontrol(...
    'CData',fm_mat('plotsel_iij'), ...
    'Parent',h0, ...
    'Units','normalized',...
    'Callback','fm_plotsel setIij', ...
    'Position',[0.1983 0.0453 0.0623 0.0924],...
    'HorizontalAlignment','center', ...
    'String','',...
    'Value',Varname.Iij,...
    'Style','togglebutton',...
    'Tag','radiobutton3');

h13 = uicontrol(...
    'CData',fm_mat('plotsel_sij'), ...
    'Parent',h0, ...
    'Units','normalized',...
    'Callback','fm_plotsel setSij', ...
    'Position',[0.2668 0.0453 0.0623 0.0924],...
    'HorizontalAlignment','center', ...
    'String','',...
    'Style','togglebutton',...
    'Value',Varname.Sij,...
    'Tag','radiobutton4');

h10 = uicontrol(...
    'CData',fm_mat('plotsel_x'), ...
    'Parent',h0, ...
    'Units','normalized',...
    'Callback','fm_plotsel setx', ...
    'HorizontalAlignment','center', ...
    'Position',[0.0611 0.1467 0.0623 0.0924],...
    'String','',...
    'Value',Varname.x,...
    'Style','togglebutton',...
    'Tag','radiobutton5');

h11 = uicontrol(...
    'CData',fm_mat('plotsel_y'), ...
    'Parent',h0, ...
    'Units','normalized',...
    'Callback','fm_plotsel sety', ...
    'HorizontalAlignment','center', ...
    'Position',[0.1297 0.1467 0.0623 0.0924],...
    'String','',...
    'Value',Varname.y,...
    'Style','togglebutton',...
    'Tag','radiobutton6');

h12 = uicontrol(...
    'CData',fm_mat('plotsel_p'), ...
    'Parent',h0, ...
    'Units','normalized',...
    'Callback','fm_plotsel setP', ...
    'Position',[0.1983 0.1467 0.0623 0.0924],...
    'HorizontalAlignment','center', ...
    'String','',...
    'Value',Varname.P,...
    'Style','togglebutton',...
    'Tag','radiobutton7');

h13 = uicontrol(...
    'CData',fm_mat('plotsel_q'), ...
    'Parent',h0, ...
    'Units','normalized',...
    'Callback','fm_plotsel setQ', ...
    'Position',[0.2668 0.1467 0.0623 0.0924],...
    'HorizontalAlignment','center', ...
    'String','',...
    'Style','togglebutton',...
    'Value',Varname.Q,...
    'Tag','radiobutton8');

h6 = uicontrol(...
    'Parent',h0, ...
    'Units','normalized',...
    'Callback','fm_plotsel fixed', ...
    'CreateFcn','fm_plotsel create_fixed', ...
    'Position',[0.3728 0.1594 0.1870 0.0453],...
    'HorizontalAlignment','left', ...
    'String','Fixed Selection',...
    'Value',Varname.fixed,...
    'Style','checkbox',...
    'Tag','checkbox_fixed');

h7 = uicontrol(...
    'Parent',h0, ...
    'Units','normalized',...
    'Callback','fm_plotsel custom', ...
    'CreateFcn','fm_plotsel create_custom', ...
    'Position',[0.3728 0.0688 0.1870 0.0453],...
    'HorizontalAlignment','left', ...
    'String','Manual Selection',...
    'Value',Varname.custom,...
    'Style','checkbox',...
    'Tag','checkbox_custom');

h1 = uicontrol( ...
    'Parent',h0, ...
    'CData',fm_mat('main_exit'), ...
    'Units','normalized', ...
    'BackgroundColor',Theme.color02, ...
    'Callback','fm_plotsel remove', ...
    'Position',[0.885 0.9 0.05 0.05], ...
    'Tag','PushRemove');

if nargout > 0, fig = h0; end

% ===============================================
function setarea(s1,s2,s3,s4)
% ===============================================

global Varname

value = get(gcbo,'Value');

hdl_fix = findobj(gcf,'Tag','checkbox_fixed');
hdl_cus = findobj(gcf,'Tag','checkbox_custom');
hdl_list1 = findobj(gcf,'Tag','listbox1');
hdl_list2 = findobj(gcf,'Tag','listbox2');
hdl_tog = findobj(gcf,'Style','togglebutton');
hdl_text1 = findobj(gcf,'Tag','StaticText1');
hdl_text2 = findobj(gcf,'Tag','StaticText2');
hdl_text3 = findobj(gcf,'Tag','StaticText3');

if value
  set(hdl_fix,'Value',s1);
  set(hdl_cus,'Value',s2);
  set(hdl_list1,'Enable',s3)
  set(hdl_tog,'Enable',s4)
  set(hdl_text1,'Enable',s3)
  set(hdl_text3,'Enable',s4)
  Varname.custom = s2;
  Varname.fixed = s1;
else
  set(hdl_fix,'Value',s2);
  set(hdl_cus,'Value',s1);
  set(hdl_list1,'Enable',s4)
  set(hdl_tog,'Enable',s3)
  set(hdl_text1,'Enable',s4)
  set(hdl_text3,'Enable',s3)
  Varname.custom = s1;
  Varname.fixed = s2;
end

% ===============================================
function setidx
% ===============================================

global Varname Bus DAE Settings Fig Areas Regions

if Varname.fixed

  Varname.idx = [];
  n1 = DAE.n+DAE.m;
  n2 = n1 + 2*Bus.n;
  n3 = 2*Settings.nseries;
  jdx = [1:(2*Settings.nseries)]';

  if Varname.x
    Varname.idx = [1:DAE.n]';
  end

  if Varname.y
    idx0 = DAE.n;
    Varname.idx = [Varname.idx; idx0+[1:DAE.m]'];
  end

  if Varname.P
    idx0 = n1;
    Varname.idx = [Varname.idx; idx0+Bus.a];
  end

  if Varname.Q
    idx0 = n1;
    Varname.idx = [Varname.idx; idx0+Bus.v];
  end

  if Varname.Pij
    idx0 = n2;
    Varname.idx = [Varname.idx; idx0+jdx];
  end

  if Varname.Qij
    idx0 = n2 + n3;
    Varname.idx = [Varname.idx; idx0+jdx];
  end

  if Varname.Iij
    idx0 = n2 + 2*n3;
    Varname.idx = [Varname.idx; idx0+jdx];
  end

  if Varname.Sij
    idx0 = n2 + 3*n3;
    Varname.idx = [Varname.idx; idx0+jdx];
  end

elseif Varname.custom

  Varname.idx = get(findobj(gcf,'Tag','listbox1'),'Value');

end

% take into account area selection
if Varname.areas(1), setzone('area'), end

% take into account region selection
if Varname.regions(1), setzone('region'), end

hdl_list2 = findobj(gcf,'Tag','listbox2');
if isempty(Varname.idx)
  set(hdl_list2,'String','<Empty>','Value',1)
else
  set(hdl_list2,'String',Varname.uvars(Varname.idx), ...
                'Value',1, ...
                'ListboxTop',1)
end

% ===============================================
function setzone(type)
% ===============================================

global DAE Areas Bus Regions Settings Varname

n1 = DAE.n+DAE.m;
n2 = n1 + 2*Bus.n;
n3 = Settings.nseries;
n4 = 2*n3;

switch type
 case 'area'
  zdx = getidx(Areas,Varname.areas);
  buses = getarea(Bus,0,0);
 case 'region'
  zdx = getidx(Regions,Varname.regions);
  buses = getregion(Bus,0,0);
end

% find buses within selected zones
bdx = find(ismember(buses,zdx));
idx = getint(Bus,getidx(Bus,bdx));

% find series components within selected zones
[fr,to] = fm_flows('onlyidx');
series1 = ismember(fr,idx);
series2 = ismember(to,idx);
ldx = find(series1+series2);

% find state and algebraic variables within selected zones
[x,y] = fm_getxy(idx);

values = [];

if Varname.x || (Varname.y && ~isempty(y))
  values = [x; DAE.n+y];
end

if Varname.y
  values = [values; DAE.n+[bdx; Bus.n+bdx]];
end

if Varname.P
  values = [values; n1+bdx];
end

if Varname.Q
  values = [values; n1+Bus.n+bdx];
end

if Varname.Pij
  values = [values; n2+ldx];
  values = [values; n2+n3+ldx];
end

if Varname.Qij
  values = [values; n2+n4+ldx];
  values = [values; n2+n3+n4+ldx];
end

if Varname.Iij
  values = [values; n2+2*n4+ldx];
  values = [values; n2+2*n4+n3+ldx];
end

if Varname.Sij
  values = [values; n2+3*n4+ldx];
  values = [values; n2+3*n4+n3+ldx];
end

values = sort(values);
Varname.idx = intersect(Varname.idx,values);